Content Management Architecture

**Referenced Files in This Document** - [tina/config.ts](file://tina/config.ts) - [tina/__generated__/types.ts](file://tina/__generated__/types.ts) - [tina/__generated__/client.ts](file://tina/__generated__/client.ts) - [src/admin/config.yml](file://src/admin/config.yml) - [.eleventy.js](file://.eleventy.js) - [package.json](file://package.json) - [src/_data/site.json](file://src/_data/site.json) - [src/_data/testimonials.json](file://src/_data/testimonials.json) - [src/_data/capabilities.json](file://src/_data/capabilities.json) - [src/admin/index.html](file://src/admin/index.html) - [src/content/news/news.11tydata.json](file://src/content/news/news.11tydata.json) - [src/content/cases/cases.11tydata.json](file://src/content/cases/cases.11tydata.json) - [src/content/team/team.11tydata.json](file://src/content/team/team.11tydata.json) - [src/content/knowledge/knowledge.11tydata.js](file://src/content/knowledge/knowledge.11tydata.js)

Table of Contents

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. Conclusion
  10. Appendices

Introduction

This document describes the content management architecture integrating TinaCMS with an Eleventy-powered static site. It covers the content schema with 10+ content types, generated TypeScript types, media management, preview and authentication flows, validation and sanitization, template rendering, and backup/export mechanisms.

Project Structure

The project is organized around:

  • TinaCMS configuration and generated client/types
  • Eleventy configuration and data collections
  • Frontend templates and static assets
  • Admin UI and CMS configuration
graph TB
subgraph "TinaCMS Layer"
CFG["tina/config.ts"]
GEN_TYPES["tina/__generated__/types.ts"]
GEN_CLIENT["tina/__generated__/client.ts"]
end
subgraph "Eleventy Layer"
ELEVENTY[".eleventy.js"]
DATA["_data/*.json"]
CONTENT["src/content/*"]
TINACMS_UI["src/admin/index.html"]
end
subgraph "Frontend"
TEMPLATES["_includes/*.njk"]
ASSETS["src/assets/*"]
end
CFG --> GEN_TYPES
CFG --> GEN_CLIENT
GEN_CLIENT --> TINACMS_UI
ELEVENTY --> DATA
ELEVENTY --> CONTENT
ELEVENTY --> TEMPLATES
TINACMS_UI --> TEMPLATES
ELEVENTY --> ASSETS

Diagram sources

  • [tina/config.ts:1-331](file://tina/config.ts#L1-L331)
  • [tina/generated/types.ts:1-800](file://tina/generated/types.ts#L1-L800)
  • [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)
  • [.eleventy.js:1-283](file://.eleventy.js#L1-L283)
  • [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)

Section sources

  • [tina/config.ts:1-331](file://tina/config.ts#L1-L331)
  • [.eleventy.js:1-283](file://.eleventy.js#L1-L283)
  • [package.json:1-32](file://package.json#L1-L32)

Core Components

  • TinaCMS configuration defines collections for content types and data files, media roots, and build output.
  • Generated TypeScript types provide strongly typed GraphQL queries and mutations for content types.
  • Eleventy builds static pages from Markdown content and JSON data, exposing collections for templates.
  • Admin UI integrates the TinaCMS client for editing.

Key responsibilities:

  • Schema definition and media configuration in tina/config.ts
  • Type-safe client usage via tina/generated/client.ts and types.ts
  • Eleventy collections for rendering and permalinks
  • Admin UI bootstrap and CMS integration

Section sources

  • [tina/config.ts:1-331](file://tina/config.ts#L1-L331)
  • [tina/generated/types.ts:1-800](file://tina/generated/types.ts#L1-L800)
  • [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)
  • [.eleventy.js:166-211](file://.eleventy.js#L166-L211)

Architecture Overview

The CMS-to-rendering pipeline:

  • TinaCMS schema drives content creation/editing and media storage.
  • Generated types and client enable type-safe queries/mutations.
  • Eleventy reads Markdown and JSON data to produce static HTML.
  • Templates render content using Eleventy collections and computed permalinks.
sequenceDiagram
participant Editor as "Editor"
participant Admin as "Admin UI<br/>src/admin/index.html"
participant Tina as "Tina Client<br/>tina/__generated__/client.ts"
participant Types as "GraphQL Types<br/>tina/__generated__/types.ts"
participant Eleventy as "Eleventy Build<br/>.eleventy.js"
participant Site as "Static Site"
Editor->>Admin : Open CMS editor
Admin->>Tina : Initialize client
Tina->>Types : Use generated types for queries/mutations
Editor->>Tina : Save content changes
Tina-->>Eleventy : Persisted content (Markdown/JSON)
Eleventy->>Eleventy : Build collections and templates
Eleventy-->>Site : Emit static HTML/CSS/JS

Diagram sources

  • [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)
  • [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)
  • [tina/generated/types.ts:1-800](file://tina/generated/types.ts#L1-L800)
  • [.eleventy.js:166-211](file://.eleventy.js#L166-L211)

Detailed Component Analysis

Content Schema and Types

The schema defines 10+ content types across folder-based Markdown collections and data file collections. Each collection specifies fields, formats, and UI behavior.

Collections overview:

  • Folder-based Markdown collections: news, cases, team, knowledge, newsletters
  • Data file collections: settings, homepage, testimonials, clients, affiliations, partners, capabilities carousel, IAA partners, resources, and multiple service pages

Field types include strings, datetimes, booleans, numbers, images, rich-text, and lists of objects. UI hints indicate titles, body content, and formatting preferences.

Generated TypeScript types:

  • Strongly typed queries and mutations for each content type
  • Filters and connections for paginated retrieval
  • Fragments for partial data fetching
classDiagram
class News {
+string title
+string date
+string author
+string excerpt
+string image
+string image_alt
+string pdf_url
+string pdf_label
+boolean featured
+boolean draft
+JSON body
}
class Cases {
+string client
+string category
+string title
+string image
+string image_alt
+string quote
+string quote_author
+number order
+boolean featured
+boolean draft
+JSON body
}
class Team {
+string anchor
+string name
+string role
+number order
+string image_index
+string image_profile
+string image_alt_index
+string image_alt_profile
+string bio_short
+boolean featured
+boolean draft
+JSON body
}
class Knowledge {
+string title
+string date
+string author
+string excerpt
+string[] tags_list
+JSON body
}
class Settings {
+string title
+string description
+string email
+string alliance_email
+string phone
+string address
+string abn
+number copyright_year
+string convertkit_form_id
+string web3forms_key
+string linkedin
}
class Homepage {
+string hero_title
+string hero_subtitle
+string hero_cta_text
+string hero_cta_url
+string capabilities_label
+string capabilities_heading
+string clients_label
+string testimonials_label
+string testimonials_heading
+string team_label
+string team_heading
+string news_label
+string news_heading
+string affiliations_label
+string affiliations_heading
+string cta_heading
+string cta_highlight
+string cta_sub
+string cta_btn_text
+string cta_btn_url
}
class Testimonials {
+object[] items
}
class Clients {
+object[] items
}
class Affiliations {
+object[] items
}
class Partners {
+object[] items
}
class CapCarousel {
+object[] items
}
class IaaPartners {
+object[] items
}
class Resources {
+object[] items
}

Diagram sources

  • [tina/config.ts:22-329](file://tina/config.ts#L22-L329)
  • [tina/generated/types.ts:222-423](file://tina/generated/types.ts#L222-L423)

Section sources

  • [tina/config.ts:22-329](file://tina/config.ts#L22-L329)
  • [tina/generated/types.ts:222-423](file://tina/generated/types.ts#L222-L423)

Generated TypeScript Types and Frontend Integration

The generated types provide:

  • Typed query/mutation operations for each content type
  • Filter types for querying subsets of content
  • Connections and edges for pagination
  • Fragments for efficient partial data loading

Integration with templates:

  • Eleventy collections supply rendered content to Nunjucks templates
  • Computed permalinks and metadata are available in templates
  • Data files (JSON) are loaded via Eleventy’s data cascade
flowchart TD
Start(["Build"]) --> GenTypes["Generate GraphQL Types<br/>tina/__generated__/types.ts"]
GenTypes --> GenClient["Create Client<br/>tina/__generated__/client.ts"]
GenClient --> AdminUI["Admin UI Loads Client<br/>src/admin/index.html"]
AdminUI --> Edit["Editor Edits Content"]
Edit --> Persist["Persist to Markdown/JSON"]
Persist --> EleventyBuild["Eleventy Build<br/>.eleventy.js"]
EleventyBuild --> Render["Render Templates<br/>with Collections/Data"]
Render --> Output["Static Site Output"]

Diagram sources

  • [tina/generated/types.ts:1-800](file://tina/generated/types.ts#L1-L800)
  • [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)
  • [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)
  • [.eleventy.js:166-211](file://.eleventy.js#L166-L211)

Section sources

  • [tina/generated/types.ts:1-800](file://tina/generated/types.ts#L1-L800)
  • [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)
  • [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)
  • [.eleventy.js:166-211](file://.eleventy.js#L166-L211)

Relationship Between TinaCMS Collections and Eleventy Data Collections

  • TinaCMS collections map to:
    • Folder-based Markdown collections (news, cases, team, knowledge, newsletters)
    • Data file collections (settings, homepage, testimonials, clients, affiliations, partners, capabilities carousel, IAA partners, resources, and service pages)
  • Eleventy exposes collections for rendering:
    • news, cases, newsletters, teamMembers, featuredNews, services, knowledge
  • Permalink behavior:
    • Some content disables permalinks (e.g., news, cases, team)
    • Knowledge uses computed permalinks for member portal routing
graph LR
subgraph "TinaCMS Collections"
T_News["news"]
T_Cases["cases"]
T_Team["team"]
T_Knowledge["knowledge"]
T_Newsletters["newsletters"]
T_Settings["settings"]
T_Homepage["homepage"]
T_Testimonials["testimonials"]
T_Clients["clients"]
T_Affiliations["affiliations"]
T_Partners["partners"]
T_CapCarousel["capabilities carousel"]
T_Iaa["IAA partners"]
T_Resources["resources"]
end
subgraph "Eleventy Collections"
E_News["news"]
E_Cases["cases"]
E_Newsletters["newsletters"]
E_Team["teamMembers"]
E_Featured["featuredNews"]
E_Services["services"]
E_Knowledge["knowledge"]
end
T_News --> E_News
T_Cases --> E_Cases
T_Team --> E_Team
T_Knowledge --> E_Knowledge
T_Newsletters --> E_Newsletters
T_Settings --> E_News
T_Homepage --> E_News
T_Testimonials --> E_News
T_Clients --> E_News
T_Affiliations --> E_News
T_Partners --> E_News
T_CapCarousel --> E_News
T_Iaa --> E_News
T_Resources --> E_News

Diagram sources

  • [tina/config.ts:22-329](file://tina/config.ts#L22-L329)
  • [.eleventy.js:166-211](file://.eleventy.js#L166-L211)
  • [src/content/news/news.11tydata.json:1-2](file://src/content/news/news.11tydata.json#L1-L2)
  • [src/content/cases/cases.11tydata.json:1-2](file://src/content/cases/cases.11tydata.json#L1-L2)
  • [src/content/team/team.11tydata.json:1-2](file://src/content/team/team.11tydata.json#L1-L2)
  • [src/content/knowledge/knowledge.11tydata.js:1-8](file://src/content/knowledge/knowledge.11tydata.js#L1-L8)

Section sources

  • [tina/config.ts:22-329](file://tina/config.ts#L22-L329)
  • [.eleventy.js:166-211](file://.eleventy.js#L166-L211)
  • [src/content/news/news.11tydata.json:1-2](file://src/content/news/news.11tydata.json#L1-L2)
  • [src/content/cases/cases.11tydata.json:1-2](file://src/content/cases/cases.11tydata.json#L1-L2)
  • [src/content/team/team.11tydata.json:1-2](file://src/content/team/team.11tydata.json#L1-L2)
  • [src/content/knowledge/knowledge.11tydata.js:1-8](file://src/content/knowledge/knowledge.11tydata.js#L1-L8)

Media Management Architecture

  • Media root configured under TinaCMS to store uploaded images.
  • Public folder for media assets is served statically.
  • Images are referenced by filename/path and used across content types and data files.
flowchart TD
Upload["Upload Image"] --> MediaRoot["Tina Media Root<br/>assets/repository/images/uploads"]
MediaRoot --> Publish["Publish Asset Path"]
Publish --> Content["Content Fields (image/image_alt)"]
Publish --> DataFiles["Data Files (logos/images)"]
Content --> Render["Template Rendering"]
DataFiles --> Render

Diagram sources

  • [tina/config.ts:15-20](file://tina/config.ts#L15-L20)
  • [src/_data/capabilities.json:1-53](file://src/_data/capabilities.json#L1-L53)
  • [src/_data/testimonials.json:1-24](file://src/_data/testimonials.json#L1-L24)

Section sources

  • [tina/config.ts:15-20](file://tina/config.ts#L15-L20)
  • [src/_data/capabilities.json:1-53](file://src/_data/capabilities.json#L1-L53)
  • [src/_data/testimonials.json:1-24](file://src/_data/testimonials.json#L1-L24)

Preview System and Live Changes

  • Development script runs Eleventy in serve mode alongside TinaCMS dev server.
  • The admin UI loads the Tina client and connects to the local GraphQL endpoint.
  • Changes made in the CMS are persisted to Markdown/JSON and reprocessed by Eleventy.
sequenceDiagram
participant Dev as "Developer"
participant Scripts as "Scripts<br/>package.json"
participant Eleventy as "Eleventy Serve"
participant TinaDev as "Tina Dev Server"
participant Browser as "Browser"
Dev->>Scripts : npm run dev : cms
Scripts->>TinaDev : Start Tina dev server
Scripts->>Eleventy : Start Eleventy --serve
Browser->>TinaDev : Connect to CMS
Browser->>Eleventy : View live site updates

Diagram sources

  • [package.json:5-12](file://package.json#L5-L12)
  • [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)

Section sources

  • [package.json:5-12](file://package.json#L5-L12)
  • [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)

Authentication Flow and Member Portal Integration

  • TinaCMS backend configured to GitHub for content storage.
  • Admin UI bootstrapped via a minimal HTML entry point.
  • Member portal content is managed via data files and service-specific collections, surfaced through Eleventy templates.
flowchart TD
Config["Tina Backend: GitHub<br/>src/admin/config.yml"] --> AdminUI["Admin UI<br/>src/admin/index.html"]
AdminUI --> Auth["Editor Login (GitHub)"]
Auth --> Edit["Edit Content"]
Edit --> Persist["Persist to Repo"]
Persist --> Build["Eleventy Build"]
Build --> MemberPortal["Member Portal Pages"]

Diagram sources

  • [src/admin/config.yml:1-774](file://src/admin/config.yml#L1-L774)
  • [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)

Section sources

  • [src/admin/config.yml:1-774](file://src/admin/config.yml#L1-L774)
  • [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)

Content Validation and Sanitization

  • Field-level validation is enforced by the schema (required fields, types).
  • UI components (e.g., rich-text, markdown) guide content creation.
  • Filtering and sorting are applied in Eleventy collections to surface validated content.
flowchart TD
Schema["Schema Fields<br/>tina/config.ts"] --> Validate["Validation Rules"]
Validate --> UI["UI Widgets<br/>src/admin/config.yml"]
UI --> Content["Persisted Content"]
Content --> Eleventy["Eleventy Collections<br/>.eleventy.js"]
Eleventy --> Render["Sanitized Rendering"]

Diagram sources

  • [tina/config.ts:22-329](file://tina/config.ts#L22-L329)
  • [src/admin/config.yml:1-774](file://src/admin/config.yml#L1-L774)
  • [.eleventy.js:166-211](file://.eleventy.js#L166-L211)

Section sources

  • [tina/config.ts:22-329](file://tina/config.ts#L22-L329)
  • [src/admin/config.yml:1-774](file://src/admin/config.yml#L1-L774)
  • [.eleventy.js:166-211](file://.eleventy.js#L166-L211)

Relationship Between Content Models and Template Rendering

  • Content models (news, cases, team, knowledge, newsletters) are rendered via Eleventy collections.
  • Data models (settings, homepage, testimonials, clients, etc.) are loaded as JSON and injected into templates.
  • Computed permalinks (e.g., knowledge) ensure consistent URLs for member portal routes.
graph TB
Models["Content Models<br/>Markdown + Front Matter"] --> Collections["Eleventy Collections<br/>.eleventy.js"]
Data["Data Models<br/>JSON Files"] --> EleventyData["Eleventy Data Cascade"]
Collections --> Templates["Nunjucks Templates"]
EleventyData --> Templates
Templates --> Output["Rendered Pages"]

Diagram sources

  • [.eleventy.js:166-211](file://.eleventy.js#L166-L211)
  • [src/content/knowledge/knowledge.11tydata.js:1-8](file://src/content/knowledge/knowledge.11tydata.js#L1-L8)
  • [src/_data/site.json:1-20](file://src/_data/site.json#L1-L20)

Section sources

  • [.eleventy.js:166-211](file://.eleventy.js#L166-L211)
  • [src/content/knowledge/knowledge.11tydata.js:1-8](file://src/content/knowledge/knowledge.11tydata.js#L1-L8)
  • [src/_data/site.json:1-20](file://src/_data/site.json#L1-L20)

Backup and Export Mechanisms

  • Content is stored as Markdown and JSON files in the repository, enabling Git-based versioning and backups.
  • TinaCMS GitHub backend ensures collaborative editing history and diffs.
  • Build artifacts are static HTML/CSS/JS, suitable for deployment and archival.

Section sources

  • [src/admin/config.yml:1-774](file://src/admin/config.yml#L1-L774)
  • [package.json:5-12](file://package.json#L5-L12)

Dependency Analysis

  • TinaCMS CLI and runtime depend on Node.js and Eleventy.
  • Generated client depends on GraphQL types.
  • Admin UI depends on the generated client.
  • Eleventy depends on data files and content Markdown.
graph LR
Node["Node.js Runtime"] --> TinaCLI["@tinacms/cli"]
Node --> TinaRuntime["tinacms"]
TinaCLI --> TypesGen["Type Generation"]
TinaRuntime --> Client["Generated Client"]
Client --> Admin["Admin UI"]
Eleventy["@11ty/eleventy"] --> Site["_site Output"]
Admin --> Site

Diagram sources

  • [package.json:14-30](file://package.json#L14-L30)
  • [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)

Section sources

  • [package.json:14-30](file://package.json#L14-L30)
  • [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)

Performance Considerations

  • Keep media assets optimized; leverage the configured media root for centralized storage.
  • Use Eleventy filters to limit and transform content efficiently.
  • Prefer fragments and targeted queries to minimize payload sizes in the CMS.

Troubleshooting Guide

Common issues and resolutions:

  • Client initialization errors: Verify the generated client URL and token configuration.
  • Missing content in collections: Confirm file paths and front matter in Markdown files.
  • Permalink mismatches: Review computed permalinks for knowledge and other dynamic routes.
  • Build failures: Ensure scripts are executed in the correct order (Tina build before Eleventy).

Section sources

  • [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)
  • [src/content/knowledge/knowledge.11tydata.js:1-8](file://src/content/knowledge/knowledge.11tydata.js#L1-L8)
  • [package.json:5-12](file://package.json#L5-L12)

Conclusion

The architecture combines TinaCMS for flexible content editing with Eleventy for robust static site generation. The schema supports diverse content types, while generated TypeScript types and a streamlined admin UI enable efficient authoring. Media, validation, and rendering are integrated to support both public and member portal experiences.

Appendices

  • Environment variables used by TinaCMS: clientId, branch, token.
  • Build and development scripts orchestrate TinaCMS and Eleventy.

Section sources

  • [tina/config.ts:3-8](file://tina/config.ts#L3-L8)
  • [package.json:5-12](file://package.json#L5-L12)